<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META NAME="generator" CONTENT="http://txt2tags.sf.net">
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>Tim's Qt4 and open source development tutorial</TITLE>

<!-- Included style.css -->
<STYLE TYPE="text/css">
body {
  padding: 2em 1em 2em 70px;
  margin: 0;
  font-family: sans-serif;
  color: black;
  background: white;
}
:link { color: #00C; background: transparent }
:visited { color: #609; background: transparent }
a:active { color: #C00; background: transparent }

a:link img, a:visited img { border-style: none } /* no border on img links */


h1, h2, h3, h4, h5, h6 { text-align: left }
h1, h2, h3 { color: #005A9C; background: white }
h1 { font: 170% sans-serif }
h2 { font: 140% sans-serif }
h3 { font: 120% sans-serif }
h4 { font: bold 100% sans-serif }
h5 { font: italic 100% sans-serif }
h6 { font: small-caps 100% sans-serif }

pre { margin-left: 2em;
      border: 1;
      padding: 4px;
      background: #ececec; }
pre, code { font-family: monospace } 


</STYLE>

</HEAD>
<BODY>

<DIV CLASS="header" ID="header">
<H1>Tim's Qt4 and open source development tutorial</H1>
<H3>(c) Tim Sutton, April 2008</H3>
</DIV>

<DIV CLASS="toc" ID="toc">
  <OL>
  <LI><A HREF="#toc1">Introduction</A>
  <LI><A HREF="#toc2">Creating a project on Google Code</A>
  <LI><A HREF="#toc3">Some considerations when starting a new project</A>
    <UL>
    <LI><A HREF="#toc4">3.1. Choosing an appropriate license</A>
    <LI><A HREF="#toc5">3.2. Defining coding standards</A>
    </UL>
  <LI><A HREF="#toc6">Using a Revision Control system</A>
  <LI><A HREF="#toc7">Patch and Diff</A>
  <LI><A HREF="#toc8">Using CMake</A>
    <UL>
    <LI><A HREF="#toc9">6.1. Hello World with CMake</A>
    <LI><A HREF="#toc10">6.2. Out of source compilation with CMake</A>
    <LI><A HREF="#toc11">6.3. Using CMake project generators</A>
    </UL>
  <LI><A HREF="#toc12">Debugging</A>
  <LI><A HREF="#toc13">The basics of writing a Qt4 based C++ app</A>
    <UL>
    <LI><A HREF="#toc14">8.1. What is Qt4?</A>
    <LI><A HREF="#toc15">8.2. Hello world for Qt4</A>
    <LI><A HREF="#toc16">8.3. Adding a button to the GUI</A>
    <LI><A HREF="#toc17">8.4. Building an interface with Designer</A>
    <LI><A HREF="#toc18">8.5. Adding a list box</A>
    <LI><A HREF="#toc19">8.6. Putting Images into our list widget</A>
    <LI><A HREF="#toc20">8.7. Qt4 Signals and Slots</A>
    <LI><A HREF="#toc21">8.8. Working with graphics</A>
    <LI><A HREF="#toc22">8.9. Some tips for moving on with learning Qt4</A>
    </UL>
  <LI><A HREF="#toc23">Unit testing</A>
    <UL>
    <LI><A HREF="#toc24">9.1. Writing a Qt4 test</A>
    <LI><A HREF="#toc25">9.2. Running tests with CMake/CTest</A>
    </UL>
  <LI><A HREF="#toc26">Managing your project and building a community</A>
    <UL>
    <LI><A HREF="#toc27">10.1. Document Everything!</A>
    <LI><A HREF="#toc28">10.2. The Decision Making Process</A>
    <LI><A HREF="#toc29">10.3. Project Roles</A>
    <LI><A HREF="#toc30">10.4. User Community Building</A>
    <LI><A HREF="#toc31">10.5. Developer Community Building</A>
    </UL>
  <LI><A HREF="#toc32">Release cycles</A>
    <UL>
    <LI><A HREF="#toc33">11.1. Phase 1 : Open Development</A>
    <LI><A HREF="#toc34">11.2. Phase 2 : Feature Freeze</A>
    <LI><A HREF="#toc35">11.3. Phase 3 : String Freeze</A>
    <LI><A HREF="#toc36">11.4. Phase 4 : Call for packaging</A>
    <LI><A HREF="#toc37">11.5. Phase 5 : Release !</A>
    </UL>
  </OL>

</DIV>
<DIV CLASS="body" ID="body">
<A NAME="toc1"></A>
<H1>1. Introduction</H1>
<P>
This tutorial will cover a wide range of topics in a very short space of time! The 
aim of this tutorial is to show you how to create an open source project from scratch! 
Although the tutorial is orientated towards Qt4 and CMake based applications, the 
things you learn here can be equally applied to <B>any other coding project</B> (for example 
java, python etc).
</P>
<P>
<IMG ALIGN="middle" SRC="overview.jpg" BORDER="0" ALT="">
</P>
<P>
We will do this all while actually building an open source project so we can can experience 
first hand how the process works. Also note that it is not the intention of this tutorial to 
make you a guru in each subject area, but rather to make you familiar with the overall process 
and give you enough information to be able to go and find more information when you need it.
</P>
<P>
<B>Note:</B> This is a 'cut and paste' tutorial - in most cases you can
simply copy the commands listed in codeblocks that look like this:
</P>
<div class="code"><PRE>
somecommand to be pasted 
</PRE></div>
<P></P>
<P>
A final note before we get started - this document itself is open source and I would welcome 
any additions / corrections / improvements to it. I can be contacted at <A HREF="mailto:tim@linfiniti.com">tim@linfiniti.com</A>.
</P>
<A NAME="toc2"></A>
<H1>2. Creating a project on Google Code</H1>
<P>
Text goes here
</P>
<A NAME="toc3"></A>
<H1>3. Some considerations when starting a new project</H1>
<P>
Starting a new project from scratch is appealing because you don't need to take
into account issues of compatibility with previous code, poor design decisions
made in the past etc. Sometimes its just nice to start on a 'clean slate'.
However if you are going to be building open source software remember that
thousands of people before you have already started open source projects, and
one of these projects may do exactly what you are planning to do! You should
always start by searching web sites like <A HREF="http://sourceforge.net">Sourceforge</A>
and <A HREF="http://freshmeat.net">Freshmeat</A> to see if there are projects out there
that do the same thing as you are planning.
</P>
<P>
Perhaps you will find there are projects similar to what you have in mind, but
missing some particular features you want. It may be a good idea to simply
download the project code (after all this is open source code after all), and
your feature and then submit a patch to the project developers. The things we
cover in this tutorial will be just as relevant for people contributing to
existing projects as it will be for those planning to start their own projects.
</P>
<P>
Sometimes you find projects similar to what you plan to do but for some reason
they are not suitable. This can often happen for reasons like:
</P>
 <UL>
 <LI>They publish their code under a license you dont agree with.
 <LI>The software is written in an unfamiliar language or a language you dont
   like (e.g. visual basic when you want a cross platform application).
 <LI>The code is incredibly messy / undocumented / disorganised and you prefer 
   to do your own project.
 </UL>

<P></P>
<P>
Regardless if you decide to create your own project from scratch, there is 
still a strong possibility that you can jump start your project by making use 
of code from existing projects and libraries. Try to do some research to see 
which open source libraries you can make use of in your project so that you 
can focus on the aspects of your project that make it unique, rather than 
repeating mundane work like writing XML parsers / command line arguments etc.
</P>
<P>
Many developers new to open source get nervous about others judging them for
writing code that is not beautiful / elegant / efficient. Also, many 'newbies'
to open source development have this idea that their project should be complete
and fully functional before releasing the code as open source. Taking this
approach is a really bad idea! Check it into the revision control system  from
your first line of code! Don't be afraid of 'its not good enough / its not
ready' type of considerations. Checking your code in early will give you a 
full revision history for your project and let you 'roll back' poor decisions 
at any time. Also if others are interested in your project, they may start 
to contribute and help you to achieve your goals faster. In short, if nobody 
can see your code, nobody can help you make it better!
</P>
<A NAME="toc4"></A>
<H2>3.1. Choosing an appropriate license</H2>
<P>
Choosing a license for your software is one thing you should decide early on in
the process. Sites like Google Code and Sourceforge will normally force you to
choose a license when you set up your project. There are many types of open
source license (some people say too many!) e.g.:
</P>
 <UL>
 <LI>GPL: viral open source license, any derived software must be released under
   the same license, no linking to proprietry software allowed.
 <LI>LGPL: As above bit linking to proprietry software is allowed.
 <LI>BSD style license: do what you like we dont care!
 <LI>Creative Commons: Useful for images, media and documentation. Can limit 
   whether derivative products are allowed (CC No Derivatives).
 </UL>

<P></P>
<P>
Bear in mind too that if you are contributing to an existing project, it is
expected that your code is submitted under the same license. Remember also that
usually open source software is not copyright free. This means if you cut &amp;
paste code from another project, you need to keep all copyright notices and
acknowledgements with the copied code - you can't suddenly claim it is your own
work!
</P>
<P>
Lastly I should add a warning about 'tainted code'. Tainted code is code that
is actually copyright and non-open source that can make its way into open
source projects. Code can also be tainted even if the authors are under
non-disclosure agreements and then write new code based on information learned
in a non-disclosure context. Incorporating tainted code into your source can
open the project up to potential legal action and cause major issues e.g. for
distributions shipping the code. In short, don't allow any code into your
project that you arent certain about its origin, and don't submit any code to
other projects if you arent the legal owner of the code.
</P>
<A NAME="toc5"></A>
<H2>3.2. Defining coding standards</H2>
<P>
One more thing that is really worth doing before starting to write any code is
to create a coding standards document. Having clearly defined coding standards
will help yourself and others to create consistent readable code, and will
streamline the addition of new developers to your project.
</P>
<P>
Your coding standards document should be as short and simple as possible
(otherwise people probably won't follow your guidelines!). Some things you may
like to cover are:
</P>
 <UL>
 <LI>file naming conventions
 <LI>class naming conventions
 <LI>method naming conventions
 <LI>variable naming conventions
 <LI>bracketing style
 <LI>indentation style
 <LI>documentation style
 </UL>

<P></P>
<P>
There are a number of excellent books and web resources available for help in
coming up with a suitable coding convention. Two sources I would recommend
(aimed at C++ and Qt4 programmers) are:
</P>
 <UL>
 <LI>'The Elements of C++ Style' by Trevor Misfeldt, Gregory Bumgardner and
   Andrew Gray ISBN 0-521-89308-9
 <LI>'Designing Qt-Style C++ APIs' Matthias Ettrich, <A HREF="http://doc.trolltech.com/qq/qq13-apis.html">http://doc.trolltech.com/qq/qq13-apis.html</A>
 <LI><A HREF="http://wiki.qgis.org/qgiswiki/DevelopersManual">http://wiki.qgis.org/qgiswiki/DevelopersManual</A> - an example of the coders guide 
   we created for the QGIS project.
 </UL>

<P></P>
<P>
As the famous saying goes, 'even a horrible coding standard is better than no
standard at all'. So I would suggest creating a simple text document called
CODING.txt and adding it to your project repository right at the start of your
project. Many IDE's and editors (KDevelop3, Eclipse, MSVC, VIM etc.) have
options to allow you to predefine various aspects of your preferred coding
style so that your code is automatically styled as your write it. Here is the
simple coding guide I typically use:
</P>
 <OL>
 <LI>For class names use a noun, written in camel case with first letter
   capitalised 
<div class="code"><PRE>
e.g. FooClass 
</PRE></div>
 <LI>Method names use a verb, written in camel case with first letter
   lower case
<div class="code"><PRE>
e.g. int doSomething (int theValue);
</PRE></div>
 <LI>For mutator methods, use the prefix 'set'
<div class="code"><PRE>
e.g. void setValue(int theValue)
</PRE></div>
 <LI>For accessor methods, do <B>not</B> use a 'get' prefix
<div class="code"><PRE>
e.g. int value ();
</PRE></div>
 <LI>Avoid abbreviations 
<div class="code"><PRE>
e.g. myPosition not myPos (follows Qt convention) 
</PRE></div>
 <LI>Class members get prefixed by 'm' 
<div class="code"><PRE>
e.g. QgsPoint mLastPosition
</PRE></div>
 <LI>Class members that are pointers get prefixed by 'mp' 
<div class="code"><PRE>
e.g. QgsPoint * mpLastPosition 
</PRE></div>
 <LI>Member parameters get prefixed by 'the' 
<div class="code"><PRE>
e.g. void foo(int theValue); 
</PRE></div>
 <LI>Member parameters that are pointers get prefixed by 'thep' 
<div class="code"><PRE>
e.g. void foo(int * thepValue); 
</PRE></div>
 <LI>Variables with local scope get prefixed with 'my'
<div class="code"><PRE>
e.g. QgsPoint myPosition; 
</PRE></div>
 <LI>Variables with local scope that are pointers get  prefixed with 'myp' 
<div class="code"><PRE>
e.g. QgsPoint * mypPosition; 
</PRE></div>
 <LI>Widgets drawn with designer get no 'm' prefix and use the following 
   prefixes to indicate what type of widget they are (this is one case 
   where we break the no abbreviations rule):
    <UL>
    <LI>QLineEdit  - 'le' 
<div class="code"><PRE>
e.g. leName
</PRE></div>
    <LI>QTextEdit  - 'te' 
<div class="code"><PRE>
e.g. teName
</PRE></div>
    <LI>QTextBrowser - 'tb' 
<div class="code"><PRE>
e.g. tbName
</PRE></div>
    <LI>QSpinBox - 'spin'
    <LI>QDoubleSpinBox - 'spin' (carries same semantics as above)
    <LI>QLabel - 'lbl'
    <LI>QGroupBox - 'grp'
    <LI>QSlider - 'slider'
    <LI>QSplitter - 'splitter'
    <LI>QTreeWidget - 'tree'
    <LI>QTreeView,QTableView,QListView - 'view' *1
    <LI>QComboBox - 'cbo'
    <LI>QCheckBox - 'cbx'
    <LI>QRadioButton - 'rad'
    <LI>QPushButton - pbn
    </UL>
 <P></P>
  *1 In general views are interchangeable, so using the same prefix for all 
  allows easily swapping e.g. a list view for a table view in designer
  without having to change any code.
 <P></P>
 <LI>Using the above scheme, its very easy to identify the scope of any variable
   for example:
<div class="code"><PRE>
void foo (QString theName,            &lt;-- method parameter 'the'
        QgsPoint * thepPoint)        &lt;-- method parameter as pointer 'thep'
{
  QString myShortName =       &lt;-- Local variable 'my'
          theName.subString(0,5);  
  QgsPoint * mypPoint =       &lt;-- Local variable as pointer 'myp'
             roundPoint(thepPoint);
  drawLabel (thepPoint,        &lt;-- Method parameter 'thep'
             mColor,           &lt;-- Member variable 'm'
             myShortName);     &lt;-- Local variable 'my'
                  
  leName-&gt;setText (            &lt;-- Designer variable from ui baseclass 'le'
                  myShortName);

}
</PRE></div>
 <P></P>
 <LI>Indentation: use 2 spaces, dont use tabs
 <LI>Bracketing: Use 'ANSI' style bracketing:
 <P></P>
<div class="code"><PRE>
class Foo 
{
  int doSomething (int theValue); 
};

int Foo::doSomething (int theValue)
{
  if (0==theValue)
  {
    return 1;
  }
  else
  {
    return 2;
  }
}

</PRE></div>
 <P></P>
 <LI>License banner: Every file added to the source repository should 
   include a banner with the GPL notice similar to this:
 <P></P>
<div class="code"><PRE>
/***************************************************************************
    foofile.cpp - A class for managing foo.
     --------------------------------------
    Date                 : 01-May-2008
    Copyright            : (C) 2008 by Tim Sutton
    Email                : tim@linfiniti.com
/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
</PRE></div>
 </OL>

<A NAME="toc6"></A>
<H1>4. Using a Revision Control system</H1>
<P>
The idea of a RCS (e.g. Subversion, CVS) is to place your code into a repository 
that lets you roll back to any point in the development cycle, and carry out 
experimental development work in a separate branch without impacting on your 
stable code base. RCS also provides an offsite backup of your code so you 
dont need to live in fear of hard disk failure, hardware theft etc.
</P>
<P>
Here is a quick primer on the key commands you will need (note that there are 
GUI applications like kdesvn / tortoisesvn that let you do this using 'point 
and click'):
</P>
<div class="code"><PRE>
svn co http://&lt;address&gt;
</PRE></div>
<P>
This will perform an initial 'checkout' (co) of the code from the repository.
When you create a new empty project on Google code, they will create an empty
SVN tree for you that you can check out and then start adding your code into
(see below).
</P>
<div class="code"><PRE>
svn update
</PRE></div>
<P>
Refreshes your local working copy with any code that may have been added to the
RCS by another developer. If you have made changes to your local copy of the
code base that conficts with the changes in the RCS, the RCS will notify you
about the conflicting files. You will need to resolve these before you can 
commit your changes.
</P>
<div class="code"><PRE>
svn resolved &lt;filename&gt;
</PRE></div>
<P>
After you have reviewed and fixed a conflicted file, you need to tell SVN this 
by using the resolved command.
</P>
<div class="code"><PRE>
svn info
</PRE></div>
<P>
This command will tell you the address of the repository, and what revision 
number you currently have checked out.
</P>
<div class="code"><PRE>
svn status [file(s)]
</PRE></div>
<P>
This will tell you the status of the files specified. This could be:
</P>
 <UL>
 <LI>'M' indicating that you have local modifications to the file, 
 <LI>'C' indicating that SVN still considers the file to be in a conflicted
   state, 
 <LI>'D' indicating the file is marked for deletion and will be removed on 
   next commit.
 <LI>'?' indicating that SVN doesnt know anything about this file (see svn add
   below)
 </UL>

<P></P>
<P>
If svn status is the same for your local file as for the file in the repository,
svn status will return nothing.
</P>
<div class="code"><PRE>
svn add &lt;file(s)&gt;
</PRE></div>
<P>
This will take local-only files that you have created and that are currently
not part of the repository and make them managed / part of the repository.
<B>Note</B> the files will not actually be pushed up to the repository until 
you do an svn commit (see below).
</P>
<div class="code"><PRE>
svn commit [file(s)]
</PRE></div>
<P>
This is the command used to push your local changes up to the server. Any new
modifications (or newly added files) will be uploaded to the RCS server after a 
commit. You will be prompted for a commit comment, which you should <B>always</B> 
add an informative comment here describing the changes you have made.
</P>
<P>
When you commit your changes, try to group files committed that relate to a 
specific new feature or improvement.
</P>
<div class="code"><PRE>
svn delete [file(s)]
</PRE></div>
<P>
Use this to mark files for deletion. On your next commit they will be removed 
from your local working copy and the repository from the revision number of 
your commit forward. Checking out an older version of the repository will 
retrieve the file.
</P>
<div class="code"><PRE>
svn revert &lt;file(s)&gt;
</PRE></div>
<P>
Rolls the local changes made in these files back to match the state they have 
in the repository. This allows you to remove changes you made locally that 
didnt work out well.
</P>
<div class="code"><PRE>
svn diff [file(s)]
</PRE></div>
<P>
This is a very useful command if you 
</P>
 <UL>
 <LI>want to see what has changed in you local copy compared to your last update
 <LI>want to send in a patch to the developers if you dont have commit access
 </UL>

<P></P>
<div class="code"><PRE>
svn export http://&lt;repository url&gt; [dirname]
</PRE></div>
<P>
Exports a copy of the code only with no SVN versioning info. Normally used 
when you want to make a source release of your code.
</P>
<P>
Most projects will give read only access to anybody (so called 'anonymous
access'), and will invite non-registered developers to submit their improvements 
by means of patches. In the 'Patch and Diff' section that follows we will examine 
this process more closely.
</P>
<P>
SVN has many more features - I've only covered the basic commands here. As you 
start to use it more, you will probably want to consult the 'red bean' SVN 
handbook more online.
</P>
<A NAME="toc7"></A>
<H1>5. Patch and Diff</H1>
<P>
What do you do if you download an opensource project, make some changes, and then 
want to submit them back to the project? Normally the project would not give you 
write access to their repository without knowing you. In this case you use the 
diff tool to create a delta file that contains only lines you have changed. Lets 
look at a little example.
</P>
<P>
<B>*Note:*</B> this will only work if you check out the project source code from SVN.
</P>
<P>
Repository file 'helloworld.txt':
</P>
<div class="code"><PRE>
hello world
</PRE></div>
<P></P>
<P>
Your local copy with changes:
</P>
<div class="code"><PRE>
Hello World
Goodbye
</PRE></div>
<P></P>
<P>
Lets make a diff file that we can send back to the project:
</P>
<div class="code"><PRE>
svn diff helloworld.txt &gt; myfix.diff
cat mydiff.diff

Index: helloworld.txt
===================================================================
--- helloworld.txt	(revision 13)
+++ helloworld.txt	(working copy)
@@ -1,1 +1,2 @@
 
- - hello world
+ - Hello World
+   Goodbye
</PRE></div>
<P></P>
<P>
You should always make your patch against the toplevel directory in the
project. Now you can email your patch to the project developers. If you are a
project developer and somebody sends you a patch, you should evaluate the patch
to ensure that the patch:
</P>
 <UL>
 <LI>does not contain malicious code
 <LI>is implemented according to your coding standards
 <LI>does not break existing functionality
 <LI>is generally desireable to have in the source tree
 </UL>

<P></P>
<P>
There are two ways to evaluate the patch before applying it. The most simple is
just to open it with a text editor and review it. There are some nice tools
such as kompare (a KDE application) that will open a diff file and give you a
graphical representation of the diff file, which for complicated patches can
make patch evaluation much easier.
</P>
<P>
The next step is to try to apply the patch to your source tree, compile and
then (assuming it compiles ok) test the changes in a runtime environment. To
apply the patch, we use a command line utility called 'patch'. Lets look at an
example:
</P>
<div class="code"><PRE>
patch -p0 &lt; bugfix.diff
</PRE></div>
<P></P>
<P>
Sometimes a patch will not apply cleanly. For example, if you have local
changes that the patch tries to override, it will cause a conflict e.g.:
</P>
<div class="code"><PRE>
patch -p0 &lt; mydiff.txt 
patching file main.cpp
Hunk #1 FAILED at 25.
1 out of 1 hunk FAILED -- saving rejects to file main.cpp.rej
</PRE></div>
<P></P>
<P>
In this case if you examine the .rej file you can determine which lines 
had problems and manually resolve the issues.
</P>
<A NAME="toc8"></A>
<H1>6. Using CMake</H1>
<P>
Makefiles are a mechanism to describe a sequence of steps that need to be carried 
out to compile your software. They are not language specific, although they are 
typically used with C/C++.
</P>
<P>
It is possible to create makefiles by hand and for simple projects this may be 
all you need to do. As your project grows in complexity though, you may want to 
switch to using a makefile generator (e.g. Automake, QMake, CMake). A makefile 
generator provides a higher level way of describing what code should be build 
and how. In this document, I will describe the basics of using CMake because 
I think its the easiest to learn while providing some really great features.
</P>
<A NAME="toc9"></A>
<H2>6.1. Hello World with CMake</H2>
<P>
Lets look at how we would compile a simple program without cmake and then with 
CMake. Here is our 'hello world' app (saved as main.cpp):
</P>
<div class="code"><PRE>
#include &lt;iostream&gt;

int main(int argc, char *argv[])
{
  std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;
  return 0;
}
</PRE></div>
<P></P>
<P>
To compile this using GCC directly, we could just do:
</P>
<div class="code"><PRE>
g++ main.cpp -o helloworld
</PRE></div>
<P></P>
<P>
This is great for a simple project but becomes impractical when you work on 
a larger project with multiple source files in multiple directories and 
linking to multiple libraries. Lets see how we can compile the same program 
using CMake (this is the contents of CMakeLists.txt):
</P>
<div class="code"><PRE>
PROJECT(helloworld)
SET(SRCS main.cpp)
ADD_EXECUTABLE(helloworld ${SRCS})
</PRE></div>
<P></P>
<P>
And here is an example of how we would generate the makefiles using our 
CMakeLists.txt:
</P>
<div class="code"><PRE>
Tim-Laptop:/tmp/helloworld timlinux$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/helloworld
</PRE></div>
<P></P>
<P>
And then to compile the software you can simply do:
</P>
<div class="code"><PRE>
Tim-Laptop:/tmp/helloworld timlinux$ make
[100%] Building CXX object CMakeFiles/helloworld.dir/main.o
Linking CXX executable helloworld
[100%] Built target helloworld
</PRE></div>
<P></P>
<P>
Finally we can run the software like this:
</P>
<div class="code"><PRE>
Tim-Laptop:/tmp/helloworld timlinux$ ./helloworld
Hello World
</PRE></div>
<P></P>
<P>
Quite simple no? The nice part is that if you have more source files you 
can just add them to the SRCS variable and they will be compiled too. 
</P>
<P>
<B>Note:</B> 'CMakeLists.txt' is a naming convention required by CMake for 
configuring your software.
</P>
<A NAME="toc10"></A>
<H2>6.2. Out of source compilation with CMake</H2>
<P>
One of the downsides to building your software in the way I have demonstrated
in the previous section is that the temporary build products are mixed in with
your source files - which is kinda messy! Just take a look at what the source 
directory for our hello world looks like before building:
</P>
<div class="code"><PRE>
Tim-Laptop:/tmp/helloworld timlinux$ ls 
CMakeLists.txt  main.cpp
</PRE></div>
<P></P>
<P>
And after building:
</P>
<div class="code"><PRE>
Tim-Laptop:/tmp/helloworld timlinux$ ls
CMakeCache.txt          CMakeLists.txt          cmake_install.cmake     
main.cpp       CMakeFiles              Makefile                helloworld
</PRE></div>
<P></P>
<P>
You can see there are a lot of generated files in our directory making it hard
to separate your real source files from ephemeral files that don't need to be
managed in your RCS.
</P>
<P>
It also makes it difficult to have debug and release builds of your software
without rebuilding everything - which can be tedious for big projects. 
</P>
<P>
CMake has a solution for this, providing support for 'out of source' building.
</P>
<P>
To build out of source, simply create a 'build' directory (you can call it 
anything you like), go into your build directory, and then run cmake, 
passing it a relative path to your sources e.g.:
</P>
<div class="code"><PRE>
Tim-Laptop:/tmp/helloworld timlinux$ mkdir build
Tim-Laptop:/tmp/helloworld timlinux$ cd build/
Tim-Laptop:/tmp/helloworld/build timlinux$ cmake ..
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Check size of void*
-- Check size of void* - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/helloworld/build
Tim-Laptop:/tmp/helloworld/build timlinux$ make
Scanning dependencies of target helloworld
[100%] Building CXX object CMakeFiles/helloworld.dir/main.o
Linking CXX executable helloworld
[100%] Built target helloworld
</PRE></div>
<P></P>
<P>
And lets look at our source directory now:
</P>
<div class="code"><PRE>
Tim-Laptop:/tmp/helloworld/build timlinux$ ls ..
CMakeLists.txt  build           main.cpp
</PRE></div>
<P></P>
<P>
The nice part is that we can tell svn to ignore any directory called 
'build' and we will have a much simpler time managing our source code.
</P>
<P>
We will see in the next section 'Debugging' how to build with debugging 
symbols enabled, and how having separate directories for 'release' and 
'debug' versions can be useful.
</P>
<A NAME="toc11"></A>
<H2>6.3. Using CMake project generators</H2>
<P>
If you are using KDevelop3 (Linux), XCode (Mac OS X) or Microsoft Visual Studio
(Windows) IDE's you can automatically generate a project file using CMake. With
this you can then open your source project in the IDE and need to make little
or no configuration changes before starting to code on your project. Here is 
how you would typically do this:
</P>
<div class="code"><PRE>
cd &lt;your project dir&gt;
mkdir build-kdevelop
cd build-kdevelop
cmake -G KDevelop3 ..
</PRE></div>
<P></P>
<P>
In the build-kdevelop directory (which you could have called anything you
like), you can open the &lt;projectname&gt;.kdevelop file using Kdevelop3 and start
to develop your code within the IDE. 
</P>
<A NAME="toc12"></A>
<H1>7. Debugging</H1>
<P>
For debugging Qt4/C++ we use the 'Gnu debugger' - gdb. Debugging is an
essential tool for interactively examining varialbles and following program
flow at run time. Lets add a couple of lines to our hello world app and I will 
show you the basics of using gdb from the command line. Note that if you are 
using an IDE like Kdevelop3 you can use the GUI to do the same things listed 
here.
</P>
<div class="code"><PRE>
#include &lt;iostream&gt;

int main(int argc, char *argv[])
{
  std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;
  int i=5;
  ++i;
  return 0;
}
</PRE></div>
<P>
You will see in the listing above that I added a couple of lines to create 
a variable 'i' - which we will try to look at while running the program. The 
next thing we need to do is to tell cmake to build in debug mode. To do that 
I will create a separate build directory for debug version of the software:
</P>
<div class="code"><PRE>
mkdir build_debug
cd build_debug
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
</PRE></div>
<P></P>
<P>
Now instead of simply running helloworld, lets start it in gdb:
</P>
<div class="code"><PRE>
gdb helloworld
run
</PRE></div>
<P></P>
<P>
In gdb we can specify a breakpoint before running and then step through our 
code examining variables as we go. Here is an example session.
</P>
<div class="code"><PRE>
Tim-Laptop:/tmp/helloworld/build_debug timlinux$ gdb helloworld
GNU gdb 6.3.50-20050815 (Apple version gdb-696) (Sat Oct 20 18:16:54 GMT 2007)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin"...
warning: --arch option not supported in this gdb.
Reading symbols for shared libraries .... done

(gdb) break main.cpp:26
Breakpoint 1 at 0x2dd0: file /tmp/helloworld/main.cpp, line 26.
(gdb) run
Starting program: /private/tmp/helloworld/build_debug/helloworld 
Reading symbols for shared libraries . done

Breakpoint 1, main (argc=1, argv=0xbffffb20) at /tmp/helloworld/main.cpp:26
26        std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;
(gdb) n
Hello World
27        int i=5;
(gdb) n
28        ++i;
(gdb) print i
$1 = 5
(gdb) n
29        return 0;
(gdb) print i
$2 = 6
(gdb) n
30      }
(gdb) q
The program is running.  Exit anyway? (y or n) y

</PRE></div>
<P>
From the above transcript, you can see that I started our helloworld 
application in GDB. Then I set a breakpoint in the file main.cpp for line 26. 
Then I used the 'n' command (you can also type 'next' out in full) to step 
over each line of code. To view the contents of a variable, use the 'print' 
command. Finally 'q' will let you exit the debugger shell.
</P>
<A NAME="toc13"></A>
<H1>8. The basics of writing a Qt4 based C++ app</H1>
<A NAME="toc14"></A>
<H2>8.1. What is Qt4?</H2>
<P>
Qt4 (pronounced 'cute4') is an cross platform, open source application
development framework. It can be used with C++ (Qt4), Python (QtPython) and
Java (QtJambi). In this tutorial we will focus on Qt4 with C++. If you program
with ANSI C++ you will need to implement many basic functions yourself for file
IO, string manipulation, networking, GUI development etc. Alternatively you can
select pre-existing libraries that provide these functions. If you select many
different libraries to provide this type of functionality you will have to deal
with different coding standards, naming conventions, library dependencies etc.
Qt4 comes to the rescue by providing a cohesive range of library functionality
with a consistent API. In addition Qt4 implements platform native GUI elements
for Windows, Mac OS X and Linux. With this GUI framework, you can write GUI
applications that will run on all these platforms (and others!) from the same
codebase. Unlike Java these applications will need to be compiled for each
platform, but with the advantage of running with optimised performance.
</P>
<P>
Qt4 is divided up into a number of 'modules':
</P>
 <UL>
 <LI><B>QtCore</B> non-GUI, core classes 
 <LI><B>QtGui</B> GUI elements (buttons, combos etc.)
 <LI><B>QtNetwork</B> network programming library (http, sockets etc.)
 <LI><B>QtOpenGL</B> classes for OpenGL programming
 <LI><B>QtSql</B> SQL databases access classes
 <LI><B>QtScript</B> classes for adding ECMA scripting support to your app
 <LI><B>QtSvg</B> SVG display and manipulation classes
 <LI><B>QtXml</B> XML parsing and creation classes (DOM, SAX and stream)
 <LI><B>QtDesigner</B> Classes for integrating custom widgets into Qt Designer
 <LI><B>QtUiTools</B> Support for using Qt Designer forms in applications
 <LI><B>QtAssistant</B> Help system infrastructure
 <LI><B>Qt3Support</B> Backwards compatibility for older Qt3 based classes
 <LI><B>QtTest</B> Unit testing library
 <LI><B>QtDBus</B> Inter-Process Communication with D-Bus (Unix only)
 </UL>

<P></P>
<P>
Qt4 also supports internationalisation, and deployment onto mobile and handheld
devices (WinCE). 
</P>
<P>
It also has its own cross platform build system (QMake) which we won't be
covering in this tutorial since I find CMake to be a better make system.
</P>
<P>
Qt4 also includes a number of applications:
</P>
 <UL>
 <LI><B>QtDesigner</B> used for visually building Graphical User Interfaces
 <LI><B>QtLinguist</B> application for translators to use to internationalise your
   app
 <LI><B>QtAssistant</B> comprehensive help and documentation (keep this open all the
   time its indispensible!)
 </UL>

<P></P>
<P>
You will discover as you use Qt4 more and more that the developers have done a
really good job - the code documentation is <B>excellent</B> with many examples
and detailed descriptions for each class. Also the classes use a very
consistent API so its usually possible to 'guess' the API of classes you
haven't used before if you have used other similar classes.
</P>
<P>
Qt4 Assistant also includes a tutorial so be sure to search the QtAssistant
documentation for 'tutorial' for mode examples.
</P>
<P>
Ok enough disussion, lets get on and write some code!
</P>
<A NAME="toc15"></A>
<H2>8.2. Hello world for Qt4</H2>
<div class="code"><PRE>
#include &lt;QApplication&gt;
#include &lt;QLabel&gt;

int main(int argc, char *argv[])
{
  // Our entry point is a QApplication
  QApplication myApp(argc,argv);
  // Lets make a simple label
  QLabel * mypLabel = new QLabel("Hello World");
  // Tell the label to show itself
  mypLabel-&gt;show();
  // Start the application event loop
  return myApp.exec();
}
</PRE></div>
<P></P>
<P>
To build the application, we need to revisit our CMakeLists.txt file we 
created back in the CMake introduction. To recap, to compile our helloworld 
application, our CMakeLists.txt looked like this:
</P>
<div class="code"><PRE>
PROJECT(helloworld)
SET(SRCS main.cpp)
ADD_EXECUTABLE(helloworld ${SRCS})
</PRE></div>
<P></P>
<P>
Now we need to add some additional lines so that Qt4 includes and linking 
can happen:
</P>
<div class="code"><PRE>
#ok this is the same as before
PROJECT(helloworld)
#so is this...
SET(SRCS main.cpp )
#tell CMake to find the Qt libs
FIND_PACKAGE(Qt4 REQUIRED) 
#tell CMake to find Qt headers
INCLUDE( ${QT_USE_FILE} ) 
#specify exactly which headers to use at compile time
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${QT_INCLUDE_DIR})
#tell cmake to use the Qt gui module
SET( QT_USE_QTGUI TRUE )
#specify the sources to compile into our exe
ADD_EXECUTABLE(helloworld MACOSX_BUNDLE ${SRCS})
#link our exe to the Qt4 Core and Gui libs
TARGET_LINK_LIBRARIES(helloworld ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
#specify what to do when typing 'make install'
INSTALL(TARGETS helloworld RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
</PRE></div>
<P></P>
<P>
Its a little more complicated than our original version but not too much! We can build the application in exactly the same way as in our cmake examples:
</P>
<div class="code"><PRE>
mkdir build
cd build
cmake ..
make
</PRE></div>
<P></P>
<P>
When you build, you will get output something like this:
</P>
<div class="code"><PRE>
-- Found Qt-Version 4.3.3
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/timlinux/dev/cpp/timsqt4tutorialrev2/build
Scanning dependencies of target helloworld
[100%] Building CXX object CMakeFiles/helloworld.dir/main.o
Linking CXX executable helloworld.app/Contents/MacOS/helloworld
[100%] Built target helloworld
</PRE></div>
<P></P>
<P>
Lets try to run it and see what happens...
</P>
<div class="code"><PRE>
./helloworld
</PRE></div>
<P></P>
<P>
<IMG ALIGN="middle" SRC="helloworld.jpg" BORDER="0" ALT="">
</P>
<A NAME="toc16"></A>
<H2>8.3. Adding a button to the GUI</H2>
<P>
Ok now we will add a button to our hello world app (QPushButton class). We also
see here how to use Qt's layout to arrange the widgets in our GUI.
</P>
<div class="code"><PRE>
// Qt4 includes
#include &lt;QApplication&gt;
#include &lt;QLabel&gt;
#include &lt;QLayout&gt; //support widget layouts
#include &lt;QPushButton&gt; //support button widget

int main(int argc, char *argv[])
{
  QApplication myApp(argc,argv);
  // A widget is the generic base class for most graphical elements
  // this will will be the base window that we put other widgets into
  QWidget * mypWidget = new QWidget();
  // Create a layout for widget placements
  QVBoxLayout * mypLayout = new QVBoxLayout();
  // Apply the layout to the widget 
  mypWidget-&gt;setLayout(mypLayout);
  // Create a label, just like before
  QLabel * mypLabel = new QLabel("Hello World");
  // Make a button and set its text to ok
  QPushButton * mypButton = new QPushButton("OK");
  // Put the label into the layout
  mypLayout-&gt;addWidget(mypLabel); //ownership is transferred to the layout!
  // Put the button in the layout
  mypLayout-&gt;addWidget(mypButton); //owndership is transferred to the layout!
  // Show the widget
  mypWidget-&gt;show();
  // note if the widget does not inherit qdialog
  // (as in the case of our mypWidget)
  // you must call app exec!
  return myApp.exec();
}
</PRE></div>
<P></P>
<P>
No changes are needed to CMakeLists.txt, just run make again to build.
</P>
<A NAME="toc17"></A>
<H2>8.4. Building an interface with Designer</H2>
<P>
While our new hello world app with its button is great, writing all our
application in our main class is not very OOP! Also building a complex GUI by
hand like this is going to take a long time! This is where we can start 
to use the excellent QtDesigner application to build our GUI.
</P>
<P>
<IMG ALIGN="middle" SRC="designer_new_dialog.jpg" BORDER="0" ALT="">
</P>
<P>
We create a new dialog with buttons, which will automatically add 'Ok' and 
'Cancel' buttons to a new dialog. Using the pallette of widgets in the 
widget toolbox you can drag and drop widgets into the dialog. I'm going 
to recreate our hello world dialog like this:
</P>
<P>
<IMG ALIGN="middle" SRC="basichelloworldui.jpg" BORDER="0" ALT="">
</P>
<P>
There are a couple of things to note in the above dialog design:
</P>
 <UL>
 <LI>The objectName is WindowBase. When we design a dialog in QtDesigner, we are
   creating an abstract base class (ABC). Adding the 'Base' suffix is a
   convention used to indicate it is an ABC. When we save the dialog we name it
   windowbase.ui - once again a naming convention that filenames get the same
   name as the class they contain. The .ui extension indicates that the file is
   a designer file - if you open it with a text editor, you will see that it is
   in fact an XML file. Qt4's 'uic' (user interface compiler) will generate the
   ABC source code from this ui file.
 <LI>The label is 'pushed' to the top of the dialog using a vertical spacer.
   A spacer is like a spring that pushes the objects on either side of it 
   apart.
 <LI>The 'OK' and 'Cancel' buttons are in a QButtonBar, which will automatically 
   implement default actions to close the dialog.
 </UL>

<P>
Now we can create a concrete class that inherits from our designer ui. First 
window.h:
</P>
<div class="code"><PRE>
#ifndef WINDOW_H
#define WINDOW_H

#include &lt;ui_windowbase.h&gt;
/** \ingroup gui
 * \brief A dialog to display our hello world message.
 */
class Window : public QDialog, private Ui::WindowBase
{
  Q_OBJECT;

  public:
  Window(QWidget* parent = 0, Qt::WFlags fl = 0 );
  ~Window();

};

#endif //sentinel
</PRE></div>
<P></P>
<P>
You will see that the Window class (named after the WindowBase ABC) uses
multiple inheritance, subclassing both QDialog and Ui::WindowBase. Inherting
QDialog will provide some basic features of a dialog, like setting the
application event loop to wait for an OK or Cancel event. Inheriting from
Ui::WindowBase makes our class have all the ui elements we defined in designer.
Next we implement window.cpp:
</P>
<div class="code"><PRE>
#include &lt;window.h&gt;
Window::Window(QWidget* parent, Qt::WFlags fl)
    : QDialog(parent,fl)
{
  //required by Qt4 to initialise the ui
  setupUi(this);
}

Window::~Window()
{
  //any cleanups you want go here
}
</PRE></div>
<P></P>
<P>
The main thing we see here is that in the constructor, we need to call
setupUi(this) so that the user interface is initialised.
</P>
<P>
Now that we have a nice OOP 'helloworld' we can get rid of our hard coded, 
programmatically created GUI code in the main.cpp main function:
</P>
<div class="code"><PRE>
#include &lt;QApplication&gt;
#include "window.h" //our custom dialog

int main(int argc, char *argv[])
{
  QApplication myApp(argc,argv);
  Window * mypWindow = new Window();
  return mypWindow-&gt;exec();
}

</PRE></div>
<P></P>
<P>
Great - we got rid of a bunch of code (always a good sign!). All we need to do
is create an instance of window, and then call its exec() method. When the user
presses 'OK' or 'Cancel' in the dialog, the application will end.
</P>
<P>
One more thing we need to do is tell CMake to compile our windowbase.ui file
into actual C++ code. Lets add some rules to out CMakeLists.txt
</P>
<div class="code"><PRE>
   PROJECT(helloworld)
   FIND_PACKAGE(Qt4 REQUIRED)
   INCLUDE( ${QT_USE_FILE} )
   # assign our ui files to a variable 'UI'
   SET(UI windowbase.ui )
   # ask Qt to generate the windowbase class
   QT4_WRAP_UI(UI_H ${UI})
   # force it to be generated
   ADD_CUSTOM_TARGET(ui ALL DEPENDS ${UI_H})
   # add our generated source and our window concrete class to the build 
   SET(SRCS main.cpp window.cpp ${UI_H})
   # define a variable stating which files should be passed through the 
   # Qt 'meta object compiler'
   SET(MOC_HDRS window.h )
   # run the qt metaobject compiler on the window class header
   QT4_WRAP_CPP(MOC_SRCS ${MOC_HDRS})
   INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}   
          ${QT_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )
   SET( QT_USE_QTGUI TRUE )
   # compile our sources and the autogenerated sources
   ADD_EXECUTABLE(helloworld MACOSX_BUNDLE ${SRCS} {MOC_SRCS})
   TARGET_LINK_LIBRARIES(helloworld ${QT_QTGUI_LIBRARY} ${QT_QTCORE_LIBRARY})
   INSTALL(TARGETS helloworld RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
</PRE></div>
<P></P>
<P>
Running 'make' in the build dir should build our improved code.
</P>
<A NAME="toc18"></A>
<H2>8.5. Adding a list box</H2>
<P>
Lets add a list widget and see how we can populate it...
</P>
<P>
<IMG ALIGN="middle" SRC="addingalistwidget.jpg" BORDER="0" ALT="">
</P>
<P>
To window.h we simply add:
</P>
<div class="code"><PRE>
private:
void fillList();
</PRE></div>
<P></P>
<P>
And to window.cpp we add:
</P>
<div class="code"><PRE>
Window::Window(QWidget* parent, Qt::WFlags fl)
    : QDialog(parent,fl)
{
  //required by Qt4 to initialise the ui
  setupUi(this);
  //we add a call to fill list to the window constructor
  fillList();
}


void Window::fillList()
{
  for (int i=0; i &lt; 20; ++i)
  {
    QListWidgetItem * mypItem = new QListWidgetItem(QString::number(i));
    listWidget-&gt;addItem(mypItem); //passes ownership to the list!
  }
}
</PRE></div>
<P></P>
<P>
Here we create 20 list widget items and add them to our list widget. Note that
ownership is passed to the list widget, and Qt will automatically delete these
when the dialog is destroyed.
</P>
<P>
Running 'make' in the build dir should build our improved code.
</P>
<A NAME="toc19"></A>
<H2>8.6. Putting Images into our list widget</H2>
<P>
A list widget can also show icons instead of text. We use the QDirIterator 
class to search for image files, and show an icon for each in our list widget. 
Qt4's file classes make working with files in C++ really easy. The changes 
we make are in designer to the 'ui' file to tell Qt to display list widget 
items as icons, and to the window.cpp class:
</P>
<div class="code"><PRE>
// Add needed headers
#include &lt;QDirIterator&gt;
#include &lt;QPixmap&gt;

// Modified fillList() method
void Window::fillList()
{
  QStringList myFilters;
  myFilters &lt;&lt; "*.jpg";
  myFilters &lt;&lt; "*.JPG";
  // QDir::Files   List directories that match the filters.
  // QDir::AllDirs List all directories; 
  // i.e. don't apply the filters to directory names.  
  QDirIterator myIterator(QApplication::applicationDirPath(),
                          myFilters,
                          QDir::Files | QDir::AllDirs,
                          QDirIterator::Subdirectories
                          );
  while (myIterator.hasNext())
  {
    QString myFileName = myIterator.next();
    QFileInfo myFileInfo(myFileName);
    if (!myFileInfo.isFile()) continue; //check the file exists
    QPixmap myPixmap(myFileName);
    QListWidgetItem * mypItem = new QListWidgetItem(myFileInfo.baseName());
    mypItem-&gt;setIcon(myPixmap);
    listWidget-&gt;addItem(mypItem); //passes ownership to the list!
  }
}
</PRE></div>
<P></P>
<P>
To the ui file, we simply change the properties of the listWidget so that the
viewMode property is set to QListView::IconView. I also set the icon size for
the list widget to 80x80. Save the 'ui' file and run make, then start the hello
world app. Any .jpg images in the app dir should appear as thumbnails.
</P>
<P>
<IMG ALIGN="middle" SRC="listwidgeticonmode.jpg" BORDER="0" ALT="">
</P>
<P>
As we shall see later, Qt4 has great tools for image manipulation. Here we used
QPixmap for loading an image from file. Once you have a QPixmap, you can pass
it to QPainter to do image manipulation, such as drawing lines, text and
gradients onto the image. For pixel by pixel manipulation, you can use the
QImage class to paint or read the value of individual pixels.
</P>
<A NAME="toc20"></A>
<H2>8.7. Qt4 Signals and Slots</H2>
<P>
No introduction to Qt4 would be complete without a demonstration of Signals 
and Slots. These are a sophisticated call back system that you can use 
to communicate application events with very little effort. Easiest way to 
explain this is to show you an example. First we tweak our dialog in designer 
to add another label and a horizontal slider.
</P>
<P>
<IMG ALIGN="middle" SRC="signalsandslotdialog.jpg" BORDER="0" ALT="">
</P>
<P>
Then in our window.h file we declare our slots:
</P>
<div class="code"><PRE>
public slots:
  /** A slot to alter the size of thumbnails based on the 
    * slider current value */
  void on_horizontalSlider_valueChanged(int theValue);
  /** A slot to show a full view of an image when its
    * thumbnail is clicked */
  void showFullItem( QListWidgetItem * thepItem );
</PRE></div>
<P></P>
<P>
There are three things going on here:
</P>
 <UL>
 <LI>We have a special declaration for slots (which can be 
   public or private, just like any normal method.
 <LI>The first slot uses 'programming by convention' naming 
   for a method that should be invoked whenever the slider is 
   moved in the gui.
 <LI>The second slot is for a method to show a full image. The 
   slot is explicitly connected to a click event in the constructor 
   of the window class as we can see below:
 </UL>

<P></P>
<P>
From window.cpp
</P>
<div class="code"><PRE>
Window::Window(QWidget* parent, Qt::WFlags fl)
    : QDialog(parent,fl)
{
  //required by Qt4 to initialise the ui
  setupUi(this);
  fillList();
  connect (listWidget, SIGNAL( itemClicked ( QListWidgetItem * )), 
      this,SLOT (showFullItem( QListWidgetItem * )));
}
</PRE></div>
<P></P>
<P>
The connect method tells Qt to route <B>signals</B> emitted when an item in 
our list widget is clicked to our showFullItem <B>slot</B>. Lets see how 
our show full item slot and slider changed slot are implemented in window.cpp:
</P>
<div class="code"><PRE>
void Window::fillList()
{  
  QStringList myFilters;  
  myFilters &lt;&lt; "*.jpg";  
  myFilters &lt;&lt; "*.JPG";  
  // QDir::Files   List directories that match the filters.  
  // QDir::AllDirs List all directories; 
  // i.e. don't apply the filters to directory names.  
  QDirIterator myIterator(QApplication::applicationDirPath(),
                          myFilters,
                          QDir::Files | QDir::AllDirs,
                          QDirIterator::Subdirectories
                          );
  while (myIterator.hasNext())
  {
    QString myFileName = myIterator.next();
    QFileInfo myFileInfo(myFileName);
    if (!myFileInfo.isFile()) continue; //check the file exists
    QPixmap myPixmap(myFileName);
    QListWidgetItem * mypItem = new QListWidgetItem(myFileInfo.baseName());
    mypItem-&gt;setIcon(myPixmap);
    //
    // Check out this new line that stores the file name
    // in a special user data area of the list widget item!
    //
    mypItem-&gt;setData(Qt::UserRole,myFileName);
    listWidget-&gt;addItem(mypItem); //passes ownership to the list!  
  }
}

void Window::on_horizontalSlider_valueChanged(int theValue)
{
  listWidget-&gt;setIconSize(QSize(theValue,theValue));
}

void Window::showFullItem( QListWidgetItem * thepItem )
{
  QString myFileName = thepItem-&gt;data(Qt::UserRole).toString();  
  QPixmap myPixmap(myFileName);
  labelFullImage-&gt;setPixmap(myPixmap);
}
</PRE></div>
<P></P>
<P>
As you can see a label widget can also show a QPixmap as well as text. A small
addition to our fillList method now stores the file name in a data area in 
each list widget item. Now when a list item is clicked, it sends a signal 
to our showFullItem slot, which then gets the filename, creates a pixmap 
and then displays it in the label. Great functionality for just a few lines 
of code!
</P>
<P>
Our horizontal slide didnt need a 'connect' call because of the way that 
we named the slot method ('programming by convention'). If you name a slot 
</P>
<div class="code"><PRE>
on_&lt;widgetname&gt;_&lt;action&gt;(parameter)
</PRE></div>
<P></P>
<P>
then Qt4 will automatically connect your slot to the signal emitted by 
&lt;widgetname&gt;. There are several other ways to create signal slot interactions, 
including visually dragging and dropping connections in designer. Build and run 
the application, it should now look something like this:
</P>
<P>
<IMG ALIGN="middle" SRC="signalsandslotsrunning.jpg" BORDER="0" ALT="">
</P>
<A NAME="toc21"></A>
<H2>8.8. Working with graphics</H2>
<P>
Lets take a look at a simple graphics manipulation. First I'm going to add a 
combo box control to our form:
</P>
<P>
<IMG ALIGN="middle" SRC="imageeffectcombo.jpg" BORDER="0" ALT="">
</P>
<P>
Next I'm going to create a new class. To create new class there are three things we need to do:
</P>
 <OL>
 <LI>Create the class definition in the header file (.h)
 <LI>Create the class implementation (.cpp)
 <LI>Add our new class to CMakeLists.txt so that CMake knows to compile it
 </OL>

<P></P>
<P>
Our new class will be called imageeffect. Here is imageeffect.h :
</P>
<div class="code"><PRE>
#ifndef IMAGEEFFECT_H
#define IMAGEEFFECT_H

#include &lt;QPixmap&gt;
#include &lt;QStringList&gt;

/** \ingroup gui
 * \brief A toolkit for applying effects to images.
  */
  class ImageEffect
{

  public:
    ImageEffect();
    ~ImageEffect();
    QStringList availableEffects() const;
    QPixmap applyEffect( const QString theEffect, const QPixmap &amp;thePixmap) const;

  private:
    QPixmap borderEffect(const QPixmap &amp;thePixmap) const;

};
#endif //sentinel
</PRE></div>
<P></P>
<P>
Ok so we can see from the API this class is going to lets use fetch a list 
of available effects, and then apply an effect. In the private section, 
we will have one example effect implementation. Watch carefully because 
I'm going to ask you to add another! Lets look at our .cpp implementation:
</P>
<div class="code"><PRE>
#include "imageeffect.h"
#include &lt;QPainter&gt;
#include &lt;QPen&gt;

ImageEffect::ImageEffect()
{
  //nothing
}

ImageEffect::~ImageEffect()
{
  //nothing
}

QStringList ImageEffect::availableEffects() const 
{
  QStringList myList;
  myList &lt;&lt; "None";
  myList &lt;&lt; "Border";
  return myList;
}

QPixmap ImageEffect::applyEffect( 
    const QString theEffect, const QPixmap &amp;thePixmap) const
{
  if ("None" == theEffect) return thePixmap;
  else if ("Border" == theEffect) return borderEffect(thePixmap);
}

QPixmap ImageEffect::borderEffect(
    const QPixmap &amp;thePixmap) const
{
  QPixmap myPixmap = thePixmap; //make a copy
  QPainter myPainter (&amp;myPixmap); //get ready to paint on our copy
  QPen myPen;
  myPen.setWidth(5);
  myPen.setColor(Qt::red);
  myPainter.setPen(myPen);
  myPainter.drawRect(0,0,myPixmap.width()-1,myPixmap.height()-1);
  myPainter.end(); //finish drawing
  return myPixmap;
}

</PRE></div>
<P></P>
<P>
Ok this code is not elegant, but its really intended to just demonstrate 
how we can manipulate an image with QPainter. We need to let window.cpp know 
about this new functionality. First we create a new private method in 
window.h:
</P>
<div class="code"><PRE>
//** Populate the list of available effects */
 void fillEffectsCombo();
</PRE></div>
<P></P>
<P>
Next we populate our combo box on window initialisetion in window.cpp:
</P>
<div class="code"><PRE>
#include "window.h"
#include "imageeffect.h"
#include &lt;QDirIterator&gt;
#include &lt;QPixmap&gt;
Window::Window(QWidget* parent, Qt::WFlags fl)
    : QDialog(parent,fl)
{
  //required by Qt4 to initialise the ui
  setupUi(this);
  fillList();
  fillEffectsCombo();
  connect (listWidget, SIGNAL( itemClicked ( QListWidgetItem * )), 
           this,SLOT (showFullItem( QListWidgetItem * )));
}

void Window::fillEffectsCombo()
{
  ImageEffect myEffect;
  comboEffects-&gt;insertItems(0,myEffect.availableEffects());
}

void Window::showFullItem( QListWidgetItem * thepItem )
{
  QString myFileName = thepItem-&gt;data(Qt::UserRole).toString();
  QPixmap myPixmap(myFileName);
  //
  // Look we apply an effect on the image before displaying it!
  //
  ImageEffect myEffect;
  myPixmap = myEffect.applyEffect(comboEffects-&gt;currentText(),myPixmap);
  labelFullImage-&gt;setPixmap(myPixmap);
}

</PRE></div>
<P></P>
<P>
I've only shown changed methods in the above example. Lastly we need to 
remember to update our CMakeLists.txt so that our new code will build!
</P>
<div class="code"><PRE>
SET(SRCS
      main.cpp 
      window.cpp
      imageeffect.cpp
      ${UI_H}
     )
</PRE></div>
<P></P>
<P>
Everything else stays the same! Simple no? Lets make, run, pick an effect 
type and you should see something like this when clicking a thumbnail.
</P>
<P>
<IMG ALIGN="middle" SRC="imageeffect.jpg" BORDER="0" ALT="">
</P>
<A NAME="toc22"></A>
<H2>8.9. Some tips for moving on with learning Qt4</H2>
 <OL>
 <LI>Always keep QtAssistant open and use the search option to quickly find 
   classes that may help you.
 <LI>Check out the Qt Quarterly articles on the [<A HREF="http://trolltech.com">http://trolltech.com</A> Trolltech
   website]
 <LI>Look at source code of other Qt4 based projects (e.g. KDE apps)
 </OL>

<P></P>
<A NAME="toc23"></A>
<H1>9. Unit testing</H1>
<P>
Unit testing is a systematic way to test your code as you write it. Unit
testing is one of the core foundations of the Extreme Programming movement.
Writing unit tests is a really good idea. Some projects / organisations will
insist that any new code contributed is accompanied with unit tests and passes
all existing unit tests.
</P>
<P>
Commonly tests will be written *before* any code implementation is written.
These tests will initially fail (which is expected). As the code implementation
is carried out, the various parts of the test will pass. When all parts pass,
the programmer knows his implementation is done!
</P>
<P>
One common trap is 'programmer laziness' - its often more fun to dive straight
into the implementation part of your code and plan to do unit testing later.
Giving your testing strategy a low priority like this means that you will
probably never get around to writing them.
</P>
<P>
CMake and Qt each provide infrastructure for unit testing:
</P>
 <UL>
 <LI>CTest : this is a 'test runner' provided with CMake that allows you to build
   and run tests as part of the make process.
 <LI>QTest : this is a module of the Qt4 library that enables testing of Qt4
   based applications (including GUI testing)
 </UL>

<P></P>
<A NAME="toc24"></A>
<H2>9.1. Writing a Qt4 test</H2>
<div class="code"><PRE>
/***************************************************************************
     imageeffecttest.cpp
     --------------------------------------
    Date                 : Sun April 28
    Copyright            : (C) 2008 Tim Sutton
    Email                : tim@linfiniti.com
 ***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
#include &lt;QtTest&gt;
#include &lt;QObject&gt;
#include &lt;QString&gt;
//header for class being tested
#include &lt;imageeffect.h&gt;

/** \ingroup UnitTests
 * This is a unit test for the ImageEffect class.
 */
class ImageEffectTest: public QObject
{
  Q_OBJECT;
  private slots:
  void testAvailableEffects(); // we will check that there are some effects available
  void testApplyEffect(); //we will try to apply each effect in turn
  void initTestCase();// will be called before the first testfunction is executed.
  void cleanupTestCase();// will be called after the last testfunction was executed.
  void init();// will be called before each testfunction is executed.
  void cleanup();// will be called after every testfunction.
  private:
  ImageEffect mEffect;
  
};

void ImageEffectTest::initTestCase()
{
  //normally you would set up anything needed for all tests here
}
void ImageEffectTest::cleanupTestCase()
{
  //here is the place to free memory etc
}
void ImageEffectTest::init()
{
  //any logic that must be run *before* each test function goes here
}
void ImageEffectTest::cleanup()
{
  //any logic that must be run *after* each test function goes here
}
void ImageEffectTest::testAvailableEffects()
{
  QStringList myList = mEffect.availableEffects();
  Q_ASSERT(myList.size() &gt; 0);
}
void ImageEffectTest::testApplyEffect()
{
  QPixmap myPixmap (80,80);
  QStringList myList = mEffect.availableEffects();
  QStringListIterator myIterator ( myList );
  while ( myIterator.hasNext() )
  {
    QString myEffectName = myIterator.next();
    {
       QPixmap myResult = mEffect.applyEffect(myEffectName,myPixmap);
       Q_ASSERT (myResult.size() == QSize(80,80));
    }
  }
}

QTEST_MAIN(ImageEffectTest);
#include "moc_imageeffecttest.cxx"
</PRE></div>
<P></P>
<A NAME="toc25"></A>
<H2>9.2. Running tests with CMake/CTest</H2>
<div class="code"><PRE>
#########################################################
# Unit testing
#########################################################
# First we set up things to includes and linking for QtTest work
SET( QT_USE_QTTEST  TRUE )
SET( QT_USE_QTGUI   TRUE )
INCLUDE( ${QT_USE_FILE} )
INCLUDE_DIRECTORIES(
      ${CMAKE_CURRENT_SOURCE_DIR} 
      ${QT_INCLUDE_DIR}
      ${CMAKE_CURRENT_BINARY_DIR}
      )
# Now we enable CTest in CMake    
ENABLE_TESTING()

#
# Now for each test we implement a block like the one below...
#

#
# ImageEffect test
#
SET(imageeffecttest_SRCS imageeffecttest.cpp imageeffect.cpp)
SET(imageeffecttest_MOC_CPPS ${imageeffecttest_SRCS})
QT4_WRAP_CPP(imageeffecttest_MOC_SRCS ${imageeffecttest_MOC_CPPS})
ADD_CUSTOM_TARGET(imageeffecttestmoc ALL DEPENDS ${imageeffecttest_MOC_SRCS})
ADD_EXECUTABLE(imageeffecttest ${imageeffecttest_SRCS})
ADD_DEPENDENCIES(imageeffecttest imageeffecttestmoc)
TARGET_LINK_LIBRARIES(imageeffecttest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
INSTALL(TARGETS imageeffecttest RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
ADD_TEST(imageeffecttest ${CMAKE_INSTALL_PREFIX}/imageeffecttest)
</PRE></div>
<P></P>
<A NAME="toc26"></A>
<H1>10. Managing your project and building a community</H1>
<P>
Managing an open source project is not a science, its an art. Your project as it 
grows will likely attract developers from around the world with different cultural 
backgrounds, languages and attitudes. Finding the best way to organise and enthuse 
these people can become just as challenging as solving the technological issues 
your project tries to address.
</P>
<P>
However there are a number of established ways and tools to organise your project.
</P>
<A NAME="toc27"></A>
<H2>10.1. Document Everything!</H2>
<P>
One of the first things you should do is create a wiki (many open source hosting 
services provide a wiki as part of their service offering). Use the wiki to 
document all the key aspects to the project. This should include design documentation, 
building from source guides, best practices guidelines, meeting records, release 
plans, FAQ's etc. If there is anything special that need to be done to work with 
your software you should basically document it.
</P>
<P>
One caveat I should note is that you should be careful to avoid documenting the 
same thing in more than one place since this will cause you additional work 
and synchronisation issues later. Sometimes its not possible to maintain a 
single copy only of certain aspects of the documentation, or you may need to 
have documentation that is syncronised to each specific release such as and 
installation guide. A good way to cater for this is to use a tool such as
text2tags (which I am using right now to create this document!). With text2tags
you can write your documentation for compilation guides, project contact info,
readme etc using the simple wiki style format and then generate plain text,
wiki markup, html etc using text2tags. Since its a plain text format, you can
keep it in your revision control system along with your source code and enjoy
all the benefits of being able to diff for changes etc.
</P>
<A NAME="toc28"></A>
<H2>10.2. The Decision Making Process</H2>
<P>
There are many ways that projects will structure their governance.
</P>
 <UL>
 <LI>Benevolent dictatorship (e.g. the Linux Kernel) where one person has
   ultimate say about what is accepted in the code base.
 <LI>Democracy all developers have write access to the code repository and have
   equal voting power in any decision making process.
 <LI>Merritocracy where developers get elevated to positions with more 
   decision making capabilities based on the quantity and quality of code 
   they have contributed.
 </UL>

<P></P>
<P>
In general most projects have some form of democracy unless they are very small.
</P>
<P>
Typically when there is a decision that needs to be made that requires the input 
of all decision makers, an email is drafted with the proposal and sent to the 
developer list. All developers can then respond with +1, 0, -1 which signify:
</P>
 <UL>
 <LI>+1 Agree with the proposal
 <LI>0  Neither agree nor disagree
 <LI>-1 Disagree with the proposal
 </UL>

<P></P>
<P>
This provides a quick and efficient way to poll developers for their opinions. 
In cases where the decisions are small, these are typically left up to the 
developers discretion as long as they fall within the defined procedures and 
coding standards for the project.
</P>
<A NAME="toc29"></A>
<H2>10.3. Project Roles</H2>
<P>
One thing you wont really find much documentation about online is how to build
and manage a team for an open source project.
</P>
<P>
Its always a good idea to try to identify specific roles (even if in small
projects one developer has to fill several of these). Having defined roles
makes if clear for outsiders to the project who they should approach for the
information they need, and allows developers to focus on areas that really
interest them.
</P>
<P>
How you compose your team will very much depend on how big your project is and 
how many contributors it has.
</P>
<P>
In a small project you may be responsible for every aspect, including coding,
documentation, replying to user and developer queries and planning and
packaging software releases. 
</P>
<P>
As your project grows you will need to get organised and divide effort as 
equally as you can between project members.
</P>
<P>
Note that in some cases it will be difficult to find volunteers to do 'grunt'
work like writing documentation - be patient and if the size &amp; popularity of
your project grows sufficiently, these kind of volunteers will eventually
emerge.
</P>
<P>
Here are some roles you may wish to identify in your project:
</P>
 <UL>
 <LI>Project manager: The 'main guy/gal' behind the project, and often the person 
   who initiated the project in the beginning.
 <LI>Release manager: Person who is responsible for overseeing and planning releases
 <LI>Documentation manager: Person responsible for maintaining user and developer
   documentation.
 <LI>Translations manager: Person responsible for managing the translation effort 
   for your project.
 <LI>Code master: Person who oversees the code base and ensures patch submissions 
   are checked and applied and that developers are adhering to the project 
   rules and standards.
 </UL>

<P></P>
<A NAME="toc30"></A>
<H2>10.4. User Community Building</H2>
<P>
An important part of developing your project is building a vibrant user community. 
Developing software without a user base for your software would be an exercise 
in futility, so don't underestimate the importance of your users. If your users 
get enthused by your software, they will perform important functions:
</P>
 <UL>
 <LI>Promoting your software to other users
 <LI>Filing bug reports
 <LI>Testing every aspect of your software and using it in ways you never expected!
 <LI>Some of them may become developers if there become interested enough
 <LI>Once users get to know your software they will start to help each other,
   reducing the support burden on developers
 </UL>

<P></P>
<P>
The first thing you should implement to build a users community is a user's 
mailing list. Keep traffic on this list focused on user issues and maintain 
a separate list for developer discussions.
</P>
<P>
Many projects implement forums and other user orientated community resources.
One thing to bear in mind is that if you spread yourself to wide across many
user facilities, you may not do a good job of servicing any of them. As such I
would suggest to start with a mailing list and only build additional resources
when you know you have the the manpower to maintain them.
</P>
<P>
There are many other things you can do to engage your user community such as 
establishing a flickr photo pool, creating a community map, writing a blog, 
twitter, facebook etc. Anything that is low maintenance on your part and 
will help the users to interact is probably worth exploring.
</P>
<A NAME="toc31"></A>
<H2>10.5. Developer Community Building</H2>
<P>
You should thing about community building in terms of your developers too. 
Remember that in general open source projects are unfunded and the only 
'remuneration' developers often receive is recognition and enhanced status.
</P>
<P>
You should work hard to ensure that your project suitably acknowledges those
who have donated their time to your project. Make sure they are listed in the
'about' box of your application (gui applications), and in an 'AUTHORS' text
file in the top level of your source tree.
</P>
<P>
There is also a really nice web site called <A HREF="http://ohloh.com">http://ohloh.com</A> where you can
register your project and your developers can build 'kudos' and get an overview
of their coding activities, which I strongly recommend registering your project
with.
</P>
<A NAME="toc32"></A>
<H1>11. Release cycles</H1>
<P>
A common mantra for open source projects is 'release early, release often'. The
idea is too release incrementally as new functionality / bug fixes become
available, rather then waiting for 'perfection' (which may never arrive!). By
putting your project in the hands of many users and other developers early and
often you will generate interest and maintain confidence that your project
undergoes active development and maintenance.  In addition, critical issues can
be picked up early in the development process, and poor design decisions can be
corrected early.
</P>
<P>
The actual process of making a software release generally has fixed phases,
which may vary depending on the size and nature of your project. Below I
present one typical sequence which you can adapt for your project.
</P>
<A NAME="toc33"></A>
<H2>11.1. Phase 1 : Open Development</H2>
<P>
This is a stage during which new features are incorporated, architectural
changes are made. New features should be approved by other project members and
if they are likely to delay a release because of long implementation times, it 
is usually better if they are developed in a branch of the revision control 
system and then merged into the main code base when they are ready for 
incorporation into the release.
</P>
<P>
One overriding guideling here should be that new development should not break
existing stable API's (unless this is by general agreement) and no code checked
into the revision control system should break the ability of other developers
to compile the software.
</P>
<A NAME="toc34"></A>
<H2>11.2. Phase 2 : Feature Freeze</H2>
<P>
This is the period in the release cycle during which everything gets tidied up.
Any bugs introduced with new features should be hunted down and squashed, new
features should be documented, api documentation should be updated up and the
code should generally be moved to a stable release ready state.
</P>
<A NAME="toc35"></A>
<H2>11.3. Phase 3 : String Freeze</H2>
<P>
For projects where the user interface is translated into multiple languages,
translators will need adequate time to translate new or changed text. During
the string freeze developers may continue with bug fixing but no strings should
be changed within the application so that the translators do not need to work
against 'moving goal posts'.
</P>
<A NAME="toc36"></A>
<H2>11.4. Phase 4 : Call for packaging</H2>
<P>
If your application is targeting multiple platforms (and it should!)
application packagers will need some time to work out any packaging issues,
commit packaging related changes and prepare the packages themselves. At this
point no other work should be ongoing in the code base in order to ensure that
the release is the same for all users on all platforms.
</P>
<A NAME="toc37"></A>
<H2>11.5. Phase 5 : Release !</H2>
<P>
This is where the web site and other avenues of publicising your software 
are updated to reflect the new version and newly available packages.
</P>
</DIV>

<!-- html code generated by txt2tags 2.4 (http://txt2tags.sf.net) -->
<!-- cmdline: txt2tags -t html -o tutorial.html tutorial.t2t -->
</BODY></HTML>
